﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Net.Sockets;
using System.Text;
using System.Threading.Tasks;

namespace CKS.PLC.Core.Reader
{
    public class SocketReaderClient
    {
        private TcpClient client;
        private string Ip;
        private int Port;
        private int TimeOut;
        public bool IsConnected => client?.Connected ?? false;
        public event Action<byte[]> ReceivedData;
        public bool HasReceived = false;

        private NetworkStream stream;
        private byte[] receiveByte = new byte[100 * 1024 * 1024];

        public SocketReaderClient SetIp(string ip)
        {
            Ip = ip;
            return this;
        }
        public SocketReaderClient SetPort(int port)
        {
            Port = port;
            return this;
        }
        public SocketReaderClient SetTimeOut(int timeOut = 2000)
        {
            TimeOut = timeOut;
            return this;
        }
        public SocketReaderClient IniSocketConnect()
        {
            try
            {
                client = new TcpClient();

                IAsyncResult connResult = client.BeginConnect(Ip, Port, null, null);
                connResult.AsyncWaitHandle.WaitOne(TimeOut, true);
                if (connResult.IsCompleted)
                {
                    stream = client.GetStream();
                    stream.BeginRead(receiveByte, 0, receiveByte.Length, ReceiveCallback, stream);
                   
                }
                else
                {
                    Close();
                }
            }
            catch
            {
                Close();
            }
            return this;
        }
        public SocketReaderClient Close()
        {
            stream?.Dispose();
            stream?.Close();
            client?.Dispose();
            client?.Close();
            return this;
        }
        // 发送数据到服务器
        public void SendData(string data)
        {
            if (!IsConnected || stream == null)
            {
                Console.WriteLine("未连接到服务器，无法发送数据");
                return;
            }

            try
            {
                byte[] buffer = Encoding.Default.GetBytes(data);
                stream.Write(buffer, 0, buffer.Length);
                stream.Flush();
                Console.WriteLine($"已发送: {data}");
            }
            catch (Exception ex)
            {
                Console.WriteLine($"发送数据失败: {ex.Message}");
                throw;
            }
        }

        string ReadText { get; set; } = string.Empty;
        public string GetReaderString()
        {
            ReadText = string.Empty;
            var tempContent = string.Empty;
            try
            {
                SendData("start");
                DateTime time = DateTime.Now;
                while (true)
                {
                    if(!ReadText.Equals(tempContent))
                        return ReadText;
                    var ts = DateTime.Now - time;
                    if (ts.TotalMilliseconds > 2000)
                        throw new Exception("读取超时");
                    Thread.Sleep(50);
                }
            }
            catch (Exception)
            {
                return IsConnected?"":"DisConnected";
            }
        }








        private void ReceiveCallback(IAsyncResult ar)
        {
            try
            {
                var sm = ar.AsyncState as NetworkStream;
                int rEnd = sm.EndRead(ar);

                if (rEnd > 0)
                {
                    byte[] data = new byte[rEnd];
                    Array.Copy(receiveByte, 0, data, 0, rEnd);
                    ReceivedData?.Invoke(data);
                    SetContent(data);
                    sm.BeginRead(receiveByte, 0, receiveByte.Length, ReceiveCallback, stream);
                }
            }
            catch (Exception ex)
            {
                try
                {
                    Close();
                    IniSocketConnect();
                }
                catch { }
            }
        }

        void SetContent(byte[] data)
        {
            try
            {
                ReadText = Encoding.UTF8.GetString(data);
            }
            catch (Exception)
            {
            }
        }


    }
}
